package com.jingdianjichi.subject.domain.service.impl;

import com.jingdianjichi.subject.common.entity.PageResult;
import com.jingdianjichi.subject.domain.convert.SubjectConverter;
import com.jingdianjichi.subject.domain.entity.SubjectAnswerBO;
import com.jingdianjichi.subject.domain.entity.SubjectInfoBO;
import com.jingdianjichi.subject.domain.entity.SubjectInfoQueryBO;
import com.jingdianjichi.subject.domain.handler.subject.SubjectTypeFactory;
import com.jingdianjichi.subject.domain.handler.subject.SubjectTypeHandler;
import com.jingdianjichi.subject.domain.service.SubjectInfoDomainService;
import com.jingdianjichi.subject.infra.basic.entity.SubjectInfo;
import com.jingdianjichi.subject.infra.basic.entity.SubjectMapping;
import com.jingdianjichi.subject.infra.basic.service.SubjectInfoService;
import com.jingdianjichi.subject.infra.basic.service.SubjectMappingService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class SubjectInfoDomainServiceImpl implements SubjectInfoDomainService {

    @Resource
    private SubjectInfoService subjectInfoService;

    @Resource
    private SubjectTypeFactory subjectTypeFactory;

    @Resource
    private SubjectMappingService subjectMappingService;
    @Override
    @Transactional
    public boolean add(SubjectInfoBO subjectInfoBO) {
        SubjectInfo subjectInfo = SubjectConverter.INSTANCE.convertBOToInfo(subjectInfoBO);
        subjectInfoService.insert(subjectInfo);
        log.info("添加题目: {}", subjectInfo);
        Integer subjectType = subjectInfoBO.getSubjectType();
        log.info("题目id{}", subjectInfo.getId());

        subjectInfoBO.getSubjectAnswerDTOList().forEach(subjectAnswerDTO -> {
            subjectAnswerDTO.setSubjectId(subjectInfo.getId());
        });
        subjectInfoBO.setId(subjectInfo.getId());
        log.info("{}",subjectInfoBO);
        boolean flagAnswer = subjectTypeFactory.getHandler(subjectType).add(subjectInfoBO);
        if (!flagAnswer) {
            throw new RuntimeException("添加答案失败");
        }
        List<Long> categoryIds = subjectInfoBO.getCategoryIds();
        List<Long> labelIds = subjectInfoBO.getLabelIds();
/*        List<SubjectMapping> subjectMappings = new ArrayList<>();
        if(categoryIds != null && !categoryIds.isEmpty()){
           if(labelIds != null && !labelIds.isEmpty()){
               for (Long categoryId : categoryIds) {
                   for (Long labelId : labelIds) {
                       SubjectMapping subjectMapping = new SubjectMapping();
                       subjectMapping.setSubjectId(subjectInfo.getId());
                       subjectMapping.setCategoryId(categoryId);
                       subjectMapping.setLabelId(labelId);
                       subjectMappings.add(subjectMapping);
                   }
               }
           }
        }*/
        /**
         * optional 检验并调用stream
         * flatMap合并
         *  map
         */
        List<SubjectMapping> subjectMappingList = Optional.ofNullable(categoryIds)
                .orElse(Collections.emptyList())
                .stream()
                .flatMap(categoryId -> Optional.ofNullable(labelIds)
                        .orElse(Collections.emptyList())
                        .stream()
                        .map(labelId -> {
                            SubjectMapping subjectMapping = new SubjectMapping();
                            subjectMapping.setSubjectId(subjectInfo.getId());
                            subjectMapping.setCategoryId(categoryId);
                            subjectMapping.setLabelId(labelId);
                            return subjectMapping;
                        })).collect(Collectors.toList());

        flagAnswer= subjectMappingService.insertBatch(subjectMappingList);

        if (!flagAnswer) {
            throw new RuntimeException("添加映射关系失败");
        }
        return flagAnswer;
    }

    /**
     * 分页查询查询题目列表
     * @param subjectInfoQueryBO
     * @return
     */
    @Override
    public PageResult<SubjectInfoBO> queryPageInfo(SubjectInfoQueryBO subjectInfoQueryBO) {

        PageResult<SubjectInfoBO> pageResult =
                new PageResult<>(subjectInfoQueryBO.getPageNo(), subjectInfoQueryBO.getPageSize());
        int start = (subjectInfoQueryBO.getPageNo() - 1) * subjectInfoQueryBO.getPageSize();
        int count = subjectInfoService.pageQueryConut(
                subjectInfoQueryBO.getSubjectDifficult(),
                subjectInfoQueryBO.getLabelId(),
                subjectInfoQueryBO.getCategoryId()
        );
        if(count  ==  0){
            return pageResult;
        }
        pageResult.setTotal(count);
        List<Long> subjectIds =subjectMappingService.pageQuery(subjectInfoQueryBO.getLabelId(),
                subjectInfoQueryBO.getCategoryId());
        List<SubjectInfo> subjectInfoList =
                subjectInfoService.pageQuery(subjectIds,
                        start ,
                        subjectInfoQueryBO.getPageSize(),
                        subjectInfoQueryBO.getSubjectDifficult());
        log.info("分页查询题目列表entity: {}", subjectInfoList);
        List<SubjectInfoBO> subjectInfoBOList = subjectInfoList.stream()
                .map(SubjectConverter.INSTANCE::convertInfoToBO)
                .collect(Collectors.toList());
        log.info("分页查询题目列表: {}", subjectInfoBOList);
        pageResult.setRecords(subjectInfoBOList);
        return pageResult;
    }

    @Override
    public SubjectInfoBO queryInfoByAllIds(SubjectInfoQueryBO subjectInfoQueryBO) {
        SubjectInfo subjectInfo = subjectInfoService.queryById(subjectInfoQueryBO.getId());
        log.info("查询题目信息: {}", subjectInfo);
        SubjectTypeHandler handler = subjectTypeFactory.getHandler(subjectInfo.getSubjectType());

        List<SubjectAnswerBO>  subjectAnswerBOList= handler.query(subjectInfo.getId());
        log.info("查询题目答案信息: {}", subjectAnswerBOList);
        SubjectInfoBO subjectInfoBO = SubjectConverter.INSTANCE.convertInfoToBO(subjectInfo);
        subjectInfoBO.setSubjectAnswerDTOList(subjectAnswerBOList);
        return subjectInfoBO;
    }
}
